package com.iretailer.report.quartz.bosPos;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.model.Malls;
import com.iretailer.report.model.Sales;
import com.iretailer.report.quartz.model.QuartTask;
import com.iretailer.report.service.MallsService;
import com.iretailer.report.service.QuartTaskService;
import com.iretailer.report.service.SalesService;
import com.iretailer.report.util.TimeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BosPosService {
    static final List<String> M_RETAIL_Column_Name = Arrays.asList("C_STORE_ID;CODE", "DOCNO", "BILLDATE", "TOT_AMT_ACTUAL", "CREATIONDATE", "ISACTIVE");

    private static final Logger log = LoggerFactory.getLogger(BosPosService.class);

    @Autowired
    private MallsService mallsService;
    @Autowired
    private SalesService salesService;
    @Autowired
    private QuartTaskService quartTaskService;


    public void execute() throws Exception {
        List<QuartTask> list = quartTaskService.list(new QueryWrapper<QuartTask>().lambda()
                .eq(QuartTask::getSpringId, "bosPosService").eq(QuartTask::getJobName, "bosPosService"));
        if (CollectionUtils.isEmpty(list)) {
            log.error("BosPosService#execute() query QuartTask null [ SpringId = bosPosService and jobName bosPosService]");
            return;
        }
        String message = list.get(0).getOtherMessage();
        if (StringUtils.isBlank(message)) {
            log.error("BosPosService#execute() otherMessage is null");
            return;
        }
        JSONArray jsonArray = JSON.parseArray(message);
        for (Object item : jsonArray) {
            JSONObject o = (JSONObject) item;
            String url = o.getString("url");
            String sipKey = o.getString("sipKey");
            String secret = o.getString("secret");
            RestUtil restUtil = new RestUtil(url, sipKey, secret);
            Integer days = o.getInteger("days");
            if (null == days) {
                days = 0;
            }
            LocalDate end = LocalDate.now();
            LocalDate start = end.plusDays(-days);
            String date = TimeUtil.localDate_format(TimeUtil.parse_LocalDate("2020-12-02"), "yyyyMMdd");
            List<Map<String, Object>> mRetail = getMRetail(restUtil, TimeUtil.localDate_format(start, "yyyyMMdd"), TimeUtil.localDate_format(end, "yyyyMMdd"));
            List<Sales> converter = converter(mRetail);
            if (CollectionUtils.isNotEmpty(converter)) {
                salesService.insertSales(converter);
            }
        }
    }

    public List<Sales> converter(List<Map<String, Object>> list) {
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        Set<String> mallCodes = list.stream().map(item -> MapUtils.getString(item, "C_STORE_ID;CODE")).collect(Collectors.toSet());
        List<Malls> malls = mallsService.list(new QueryWrapper<Malls>().lambda().in(Malls::getMallCode, mallCodes));
        Map<String, Malls> mallsMap = malls.stream().collect(Collectors.toMap(Malls::getMallCode, a -> a, (n, o) -> n));
        List<Sales> result = new ArrayList<>(list.size());

        for (Map<String, Object> item : list) {
            if (!check(item)) {
                continue;
            }
            String mallCode = MapUtils.getString(item, "C_STORE_ID;CODE");
            if (MapUtils.isEmpty(mallsMap) || !mallsMap.containsKey(mallCode)) {
                continue;
            }
            Malls mall = mallsMap.get(mallCode);
            Sales sales = new Sales();
            String creationdate = MapUtils.getString(item, "CREATIONDATE");
            String billdate = MapUtils.getString(item, "BILLDATE");
            sales.setId(MapUtils.getString(item, "DOCNO"));
            sales.setDate(TimeUtil.parse_LocalDate(billdate, "yyyyMMdd"));
            sales.setTime(TimeUtil.parse_LocalDateTime(creationdate, "yyyy-MM-dd HH:mm:ss.S"));
            Double tot_amt_actual = MapUtils.getDouble(item, "TOT_AMT_ACTUAL");
            sales.setSales(tot_amt_actual);
            sales.setReceipts(1);
            sales.setPieces(1);
            sales.setMallId(mall.getId());
            result.add(sales);
        }
        return result;
    }

    private List<Map<String, Object>> getMRetail(RestUtil restUtil, String startDate, String endDate) throws Exception {
        String command = "Query";
        JSONObject jo = new JSONObject();
        jo.put("table", "M_RETAIL");
        // "DOCNO" 单据编号  "C_STORE_ID;NAME" 店仓  "BILLDATE" 单据日期
        jo.put("columns", M_RETAIL_Column_Name);
        jo.put("start", 0);
        jo.put("range", true);//返回行数
        jo.put("count", true);
        JSONObject params = new JSONObject();
        params.put("condition", " STATUS = '2' and BILLDATE BETWEEN '" + startDate + "' AND '" + endDate + "'");
        jo.put("params", params);
        String msg = restUtil.rest(command, jo);
        if (StringUtils.isBlank(msg)) {
            return Collections.emptyList();
        }
        JSONArray objects = JSON.parseObject(msg, JSONArray.class);
        if (CollectionUtils.isNotEmpty(objects)) {
            JSONObject jsonObject = (JSONObject) objects.get(0);
            String code = jsonObject.getString("code");
            if ("0".equals(code)) {
                JSONArray rows = jsonObject.getJSONArray("rows");
                List<Map<String, Object>> result = new ArrayList<>(rows.size());
                int isactiveIndex = M_RETAIL_Column_Name.indexOf("ISACTIVE");
                for (Object row : rows) {
                    JSONArray r = (JSONArray) row;
                    if (isactiveIndex >= 0) {
                        if (!"是".equals(r.getString(isactiveIndex))) {
                            continue;
                        }
                    }
                    HashMap<String, Object> rowMap = new HashMap<>();
                    for (int i = 0; i < M_RETAIL_Column_Name.size(); i++) {
                        rowMap.put(M_RETAIL_Column_Name.get(i), r.get(i));
                    }
                    result.add(rowMap);
                }
                return result;
            } else {
                log.error("query M_RETAIL : {}", jsonObject.toJSONString());
                return Collections.emptyList();
            }
        } else {
            return Collections.emptyList();
        }
    }

    private boolean check(Map<String, Object> map) {
        for (String key : M_RETAIL_Column_Name) {
            if (!(map.containsKey(key) && !Objects.isNull(map.get(key)))) {
                return false;
            }
        }
        return true;
    }
}
